#region using statements

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

using NGen.Managers.Logging;

using Nuclex.Input;

#endregion

namespace NGen.Managers.Input
{
	/// <summary>
	/// 	Manager for grabbing input and throwing the input events
	/// </summary>
	public sealed class ManagerInput : GameManager, IManagerInput
	{
		#region local fields

		private readonly InputManager m_inputManager;

		#endregion

		#region constructors

		public ManagerInput() {
			m_inputManager = new InputManager();
			GameEngine.GameServices.AddService(typeof(IInputService), m_inputManager);
			CurrentLoggingLevel = LoggingLevel.MINIMAL;
			Logger = GameEngine.GetService<IManagerLogs>().Log<ManagerInput>();
			SkipDraw = true;
			UpdateOrder = 0;
		}

		#endregion

		#region IGameManager implementation

		///<summary>
		///	update the manager
		///</summary>
		///<param name = "p_gameTime">snapshot of timing values</param>
		internal override void Update(GameTime p_gameTime) {
			m_inputManager.Update();
		}

		/// <summary>
		/// 	cleanup the manager
		/// </summary>
		internal override void Cleanup() {
			GameEngine.GameServices.RemoveService(typeof(IInputService));
		}

		#endregion

		#region IManagerInput implmentation

		/// <summary>
		/// 	Register an object to receive keyboard input events
		/// </summary>
		/// <param name = "p_listener">object to listen</param>
		public void AddKeyboardListener(IKeyboardListener p_listener) {
			m_inputManager.GetKeyboard().KeyPressed += p_listener.KeyPressed;
			m_inputManager.GetKeyboard().KeyReleased += p_listener.KeyReleased;
			Logger.Write(Logger.BuildString(GetType().Name).Append(": keyboard listener added -> ").Append(p_listener.GetType().Name).ToString(), CurrentLoggingLevel);
		}

		/// <summary>
		/// 	Unregister an object from receiving keyboard input events
		/// </summary>
		/// <param name = "p_listener">object to stop listening</param>
		public void RemoveKeyboardListener(IKeyboardListener p_listener) {
			m_inputManager.GetKeyboard().KeyPressed -= p_listener.KeyPressed;
			m_inputManager.GetKeyboard().KeyReleased -= p_listener.KeyReleased;
			Logger.Write(Logger.BuildString(GetType().Name).Append(": keyboard listener removed -> ").Append(p_listener.GetType().Name).ToString(), CurrentLoggingLevel);
		}

		/// <summary>
		/// 	Register an object to receive mouse input events
		/// </summary>
		/// <param name = "p_listener">object to listen</param>
		public void AddMouseListener(IMouseListener p_listener) {
			m_inputManager.GetMouse().MouseButtonPressed += p_listener.MousePressed;
			m_inputManager.GetMouse().MouseButtonReleased += p_listener.MouseReleased;
			m_inputManager.GetMouse().MouseMoved += p_listener.MouseMoved;
			m_inputManager.GetMouse().MouseWheelRotated += p_listener.MouseWheelScroll;
			Logger.Write(Logger.BuildString(GetType().Name).Append(": mouse listener added -> ").Append(p_listener.GetType().Name).ToString(), CurrentLoggingLevel);
		}

		/// <summary>
		/// 	Unregister an object from receiving mouse input events
		/// </summary>
		/// <param name = "p_listener">object to lister</param>
		public void RemoveMouseListener(IMouseListener p_listener) {
			m_inputManager.GetMouse().MouseButtonPressed -= p_listener.MousePressed;
			m_inputManager.GetMouse().MouseButtonReleased -= p_listener.MouseReleased;
			m_inputManager.GetMouse().MouseMoved -= p_listener.MouseMoved;
			m_inputManager.GetMouse().MouseWheelRotated -= p_listener.MouseWheelScroll;
			Logger.Write(Logger.BuildString(GetType().Name).Append(": mouse listener removed -> ").Append(p_listener.GetType().Name).ToString(), CurrentLoggingLevel);
		}

		/// <summary>
		/// 	Get the current state of the keyboard
		/// </summary>
		/// <returns>the keyboard state</returns>
		public KeyboardState GetKeyboardState() {
			return m_inputManager.GetKeyboard().GetState();
		}

		/// <summary>
		/// 	Get the current state of the mouse
		/// </summary>
		/// <returns>the mouse state</returns>
		public MouseState GetMouseState() {
			return m_inputManager.GetMouse().GetState();
		}

		#endregion
	}
}